﻿
namespace TestFsWeb

open System
open System.Xml
open System.Xml.Linq

type internal ChatMessage =
    | Send of string
    | Clear
    | Get of AsyncReplyChannel<string>

type ChatRoomAgent()=
    // ********************** primary constructor
    let m_mailbox = MailboxProcessor.Start(fun inbox ->
        let rec loop received = async {
            let! msg = inbox.Receive()
            match msg with
                | Send(text) ->
                    let newelement = new XElement(XName.Get("li"),text)
                    return! loop (newelement :: received)
                | Clear ->
                    return! loop []
                | Get(channel) ->
                    let html = new XElement(XName.Get("ul"),received)
                    channel.Reply <| html.ToString(SaveOptions.DisableFormatting)
                    return! loop received
        } // async
        loop []
    )

    // ********************** members
    member this.Send text =
        m_mailbox.Post <| Send(text)

    member this.Clear() =
        m_mailbox.Post Clear

    member this.Get() =
        m_mailbox.PostAndReply (fun channel -> Get(channel))

    member this.AsyncGet(?timeout : int) =
        m_mailbox.PostAndAsyncReply((fun channel -> Get(channel)),?timeout = timeout)

    interface IDisposable with
        member this.Dispose() =
            (m_mailbox :> IDisposable).Dispose()

module TestChatRoomAgent =
    let main() =
        use chatter = new ChatRoomAgent()
        
        ["hello";"F#";"from WSU"]
        |> List.rev
        |> Seq.iter chatter.Send

        printfn "%s" <| chatter.Get()

        chatter.Clear()
        printfn "after clearing: \n%s" <| chatter.Get()
        
